package com.qidian.blog.factory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @Author 郭浩
 * @Date 2022/10/11 16:10
 */
public class ServiceFactory {
    private static Map<Class,Object> map = new HashMap<>();
    // 存储当前实现类所有的接口和实现类对应的关系
    private static Map<Class,Class> aliasesMap = new HashMap<>();


    public static <T> T getService(Class<T> clazz){
        T t = null;
        if(aliasesMap.containsKey(clazz)){
            // 获取实现类类型
            Class clz = aliasesMap.get(clazz);
            // 获取具体的对象
            Object o = map.get(clz);
            return clazz.cast(o);
        }
        return t;
    }


    static {
        // 读取配置文件，加载所有的mapper
        Properties ps = new Properties();
        InputStream in = MapperFactory.class.getClassLoader().getResourceAsStream("service.properties");
        try {
            ps.load(in);
            // 读取所有的属性
            Collection<Object> values = ps.values();
            for (Object obj : values){
                String className = obj.toString();
                try {
                    Class<?> clazz = Class.forName(className);
                    // 创建类对象
                    Object instance = clazz.newInstance();
                    // 将service对象放入map，map的可以是service实现类的接口类型
                    Class<?>[] interfaces = clazz.getInterfaces();
                    for (Class clz : interfaces){
                        aliasesMap.put(clz,clazz);
                    }
                    // 将对象放入map
                    map.put(clazz,instance);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    throw new RuntimeException("类名:"+className+"有误");
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
